#ifndef ONB_HPP
# define ONB_HPP
# pragma once

#include "vector.hpp"

namespace etl
{

//////////////////////////////////////////////////////////////////////////////
template <typename T>
inline constexpr ::etl::vector<T, 3> ortho(::etl::vector<T, 2> const& u)
{
  return {-u(1), u(0)};
}

//////////////////////////////////////////////////////////////////////////////
template <typename T>
inline ::etl::vector<T, 3> ortho(::etl::vector<T, 3> const& u)
{
  auto const u0(::std::abs(u(0)));
  auto const u1(::std::abs(u(1)));
  auto const u2(::std::abs(u(2)));

  return (u0 < u1) && (u0 < u2) ?
    decltype(ortho(u)){T(0), -u(2), u(1)} :
      (u1 < u0) && (u1 < u2) ?
        decltype(ortho(u)){-u(2), T(0), u(0)} :
        decltype(ortho(u)){-u(1), u(0), T(0)};
}

//////////////////////////////////////////////////////////////////////////////
template <::std::size_t V, typename T>
inline typename ::std::enable_if<
  0 == V,
  ::etl::vector<T, 3>
>::type
ortho(::etl::vector<T, 3> const& u)
{
  auto tmp(cross(::etl::vector<T, 3>{T(1), T(0), T(0)}, u));

  return ::std::abs(::etl::dot(tmp, tmp)) > T(.1) ?
    tmp :
    ::etl::cross(::etl::vector<T, 3>{T(0), T(1), T(0)}, u);
}

}

#endif // ONB_HPP
